home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
FROMUTS
/
LITTLEST
/
!LittleST
/
st
/
MAG
< prev
next >
Wrap
Text File
|
1989-03-14
|
16KB
|
756 lines
*
* Little Smalltalk, version 3
* Written by Tim Budd, Oregon State University, July 1988
*
* Classes dealing with objects having Magnitude
*
Class Magnitude Object
Class Char Magnitude value
Class Number Magnitude
Class Integer Number
Class LongInteger Integer negative digits
Class Fraction Number top bottom
Class Float Number
Class Random Object
*
Methods Object 'magnitude'
isNumber
^ false
|
isFloat
^ false
|
isFraction
^ false
|
isInteger
^ false
|
isLongInteger
^ false
|
isShortInteger
^ false
]
Methods Char 'all'
< aValue
" can only compare characters to characters "
^ aValue isChar
ifTrue: [ value < aValue asInteger ]
ifFalse: [ smalltalk error: 'char compared to nonchar']
|
== aValue
^ aValue isChar
ifTrue: [ value = aValue asInteger ]
ifFalse: [ false ]
|
asInteger
^ value
|
asString
" make ourselves into a string "
^ ' ' copy; at: 1 put: self
|
digitValue
" return an integer representing our value "
self isDigit ifTrue: [ ^ value - $0 asInteger ].
self isUppercase ifTrue: [ ^ value - $A asInteger + 10 ].
^ smalltalk error: 'illegal conversion, char to digit'
|
isAlphabetic
^ (self isLowercase) or: [ self isUppercase ]
|
isAlphaNumeric
^ (self isAlphabetic) or: [ self isDigit ]
|
isBlank
^ value = $ " blank char "
|
isChar
^ true
|
isDigit
^ value between: $0 asInteger and: $9 asInteger
|
isLowercase
^ value between: $a asInteger and: $z asInteger
|
isUppercase
^ value between: $A asInteger and: $Z asInteger
|
value: aValue " private - used for initialization "
value <- aValue
|
printString
^ '$', self asString
]
Methods Fraction 'all'
= f
f isFraction
ifTrue: [ ^ (top = f top) and: [ bottom = f bottom ] ]
ifFalse: [ ^ super = f ]
|
< f
f isFraction
ifTrue: [ ^ (top * f bottom) < (bottom * f top) ]
ifFalse:[ ^ super < f ]
|
+ f
f isFraction
ifTrue: [ ^ ((top * f bottom) + (bottom * f top)) /
(bottom * f bottom) ]
ifFalse:[ ^ super + f ]
|
- f
f isFraction
ifTrue: [ ^ ((top * f bottom) - (bottom * f top)) /
(bottom * f bottom) ]
ifFalse:[ ^ super - f ]
|
* f
f isFraction
ifTrue: [ ^ (top * f top) / (bottom * f bottom) ]
ifFalse: [ ^ super * f ]
|
/ f
^ self * f reciprocal
|
abs
^ top abs / bottom
|
asFloat
" convert to a floating point number "
^ top asFloat / bottom asFloat
|
truncated
" convert to an integer rounded towards zero "
^ top quo: bottom
|
bottom
^ bottom
|
coerce: x
" coerce a value into being a fraction "
^ x asFraction
|
generality
" generality value - used in mixed type arithmetic "
^ 5
|
isFraction
^ true
|
ln
^ (top ln) - (bottom ln)
|
raisedTo: x
^ (top raisedTo: x) / (bottom raisedTo: x)
|
reciprocal
^ bottom / top
|
top
^ top
|
with: t over: b
" initialization "
top <- t.
bottom <- b
|
printString
^ top printString, '/', bottom printString
]
Methods Float 'all'
+ value
^ value isFloat
ifTrue: [ <110 self value> " floating add " ]
ifFalse: [ super + value ]
|
- value
^ value isFloat
ifTrue: [ <111 self value> " floating subtract " ]
ifFalse: [ super - value ]
|
< value
^ value isFloat
ifTrue: [ <112 self value> " floating comparison " ]
ifFalse: [ super < value ]
|
= value
^ value isFloat
ifTrue: [ <116 self value> ]
ifFalse: [ super = value ]
|
* value
^ value isFloat
ifTrue: [ <118 self value> ]
ifFalse: [ super * value ]
|
/ value
^ value isFloat
ifTrue: [ (value = 0.0)
ifTrue: [ smalltalk error:
'float division by zero' ]
ifFalse: [ <119 self value> ]]
ifFalse: [ super / value ]
|
isFloat
^ true
|
coerce: value
" convert the value into a floating point number "
^ value asFloat
|
exp
" return e raised to self "
^ <103 self>
|
generality
" our numerical generality - used for mixed mode arithmetic"
^ 7
|
integerPart | i j |
i <- <106 self>. j <- i basicAt: 2. i <- i basicAt: 1.
j < 0 ifTrue: [ ^ 0 ] ifFalse: [ ^ i * (2 raisedTo: j)]
|
ln
" natural log of self "
^ <102 self>
|
new
^ smalltalk error: 'cannot create floats with new'
|
printString
^ <101 self>
|
quo: value
^ (self / value) truncated
|
rounded
^ (self + 0.5) floor
|
truncated | result f i |
" truncate to an integer rounded towards zero"
f <- self. result <- 0.
[ i <- f integerPart. i > 0] whileTrue:
[ result <- result + i. f <- f - i ].
^ result
]
Methods Integer 'all'
+ value | r |
^ (self isShortInteger and: [value isShortInteger])
ifTrue: [ r <- <60 self value>.
"primitive will return nil on overflow"
r notNil ifTrue: [ r ]
ifFalse: [ self asLongInteger + value asLongInteger ]]
ifFalse: [ super + value ]
|
- value | r |
^ (self isShortInteger and: [value isShortInteger])
ifTrue: [ r <- <61 self value>.
"primitive will return nil on overflow"
r notNil ifTrue: [ r ]
ifFalse: [ self asLongInteger - value asLongInteger ]]
ifFalse: [ super - value ]
|
< value
^ (self isShortInteger and: [value isShortInteger])
ifTrue: [ <62 self value> ]
ifFalse: [ super < value ]
|
> value
^ (self isShortInteger and: [value isShortInteger])
ifTrue: [ <63 self value> ]
ifFalse: [ super > value ]
|
= value
^ (self isShortInteger and: [value isShortInteger])
ifTrue: [ self == value ]
ifFalse: [ super = value ]
|
* value | r |
^ (self isShortInteger and: [value isShortInteger])
ifTrue: [ r <- <68 self value>.
"primitive will return nil on overflow"
r notNil ifTrue: [ r ]
ifFalse: [ self asLongInteger * value asLongInteger ]]
ifFalse: [ super * value ]
|
/ value | t b |
value = 0 ifTrue: [ ^ smalltalk error: 'division by zero'].
value isInteger
ifTrue: [ b <- self gcd: value .
t <- self quo: b.
b <- value quo: b.
b negative
ifTrue: [ t <- t negated.
b <- b negated ].
(b = 1) ifTrue: [ ^ t ].
^ Fraction new; with: t over: b ]
ifFalse: [ ^ super / value ]
|
, value
" used to make long integer constants "
^ self * 1000 + value
|
allMask: value
" see if all bits in argument are on"
^ value = (self bitAnd: value)
|
anyMask: value
" see if any bits in argument are on"
^ 0 ~= (self bitAnd: value)
|
asCharacter
^ Char new; value: self
|
asDigit
" return as character digit "
(self >= 0)
ifTrue: [ (self <= 9) ifTrue:
[ ^ (self + $0 asInteger) asCharacter ].
(self < 36) ifTrue:
[ ^ (self + $A asInteger - 10) asCharacter ] ].
^ smalltalk error: 'illegal conversion, integer to digit'
|
asFloat
" should be redefined by any subclasses "
self isShortInteger ifTrue: [ ^ <51 self> ]
|
asFraction
^ Fraction new ; with: self over: 1
|
asLongInteger | newList i |
newList <- List new.
i = 0 ifTrue: [ newList add: 0 ]
ifFalse: [ i <- self abs.
[ i ~= 0 ] whileTrue:
[ newList addLast: (i rem: 100).
i <- i quo: 100 ] ].
^ LongInteger new; sign: i negative digits: newList asArray
|
asString
^ self radix: 10
|
bitAnd: value
^ (self isShortInteger and: [value isShortInteger])
ifTrue: [ <71 self value > ]
ifFalse: [ smalltalk error:
'arguments to bit operation must be short integer']
|
bitAt: value
^ (self bitShift: 1 - value) bitAnd: 1
|
bitInvert
"invert all bits in self"
^ self bitXor: -1
|
bitOr: value
^ (self bitXor: value) bitXor: (self bitAnd: value)
|
bitXor: value
^ (self isShortInteger and: [value isShortInteger])
ifTrue: [ <72 self value > ]
ifFalse: [ smalltalk error:
'argument to bit operation must be integer']
|
bitShift: value
^ (self isShortInteger and: [value isShortInteger])
ifTrue: [ <79 self value > ]
ifFalse: [ smalltalk error:
'argument to bit operation must be integer']
|
even
^ (self rem: 2) = 0
|
factorial
^ (2 to: self) inject: 1 into: [:x :y | x * y ]
|
gcd: value
(value = 0) ifTrue: [ ^ self ].
(self negative) ifTrue: [ ^ self negated gcd: value ].
(value negative) ifTrue: [ ^ self gcd: value negated ].
(value > self) ifTrue: [ ^ value gcd: self ].
^ value gcd: (self rem: value)
|
generality
" generality value - used in mixed class arithmetic "
^ 2
|
isShortInteger
^ true
|
lcm: value
^ (self quo: (self gcd: value)) * value
|
new
^ smalltalk error: 'cannot create integers with new'
|
odd
^ (self rem: 2) ~= 0
|
quo: value | r |
^ (self isShortInteger and: [value isShortInteger])
ifTrue: [ r <- <69 self value>.
(r isNil)
ifTrue: [ smalltalk error:
'quo: or rem: with argument 0']
ifFalse: [ r ]]
ifFalse: [ ^ super quo: value ]
|
radix: base | sa text |
" return a printed representation of self in given base"
sa <- self abs.
text <- (sa \\ base) asDigit asString.
^ (sa < base)
ifTrue: [ (self negative)
ifTrue: [ '-' , text ]
ifFalse: [ text ]]
ifFalse: [ ((self quo: base) radix: base), text ]
|
truncated
^ self
|
printString
^ self asString
|
timesRepeat: aBlock | i |
" use while, which is optimized, not to:, which is not"
i <- 0.
[ i < self ] whileTrue:
[ aBlock value. i <- i + 1]
]
Methods LongInteger 'all'
< n | result |
n isLongInteger
ifFalse: [ ^ super < n ].
(negative == n negative) ifFalse: [ ^ negative ].
" now either both positive or both negative "
result <- false.
self with: n bitDo:
[:x :y | (x ~= y) ifTrue: [ result <- x < y]].
negative ifTrue: [ result <- result not ].
^ result
|
= n
n isLongInteger
ifFalse: [ ^ super = n ].
(negative == n negative) ifFalse: [ ^ false ].
^ digits = n digits
|
+ n | newDigits z carry |
n isLongInteger
ifFalse: [ ^ super + n ].
negative ifTrue: [ ^ n - self negated ].
n negative ifTrue: [ ^ self - n negated ].
" reduced to positive + positive case "
newDigits <- List new. carry <- 0.
self with: n bitDo:
[:x :y | z <- x + y + carry.
(z >= 100) ifTrue: [ carry <- 1. z <- z - 100]
ifFalse: [ carry <- 0 ].
newDigits addLast: z ].
carry > 0 ifTrue: [ newDigits addLast: carry ].
^ LongInteger new; sign: false digits: newDigits asArray
|
- n | result newDigits z borrow |
n isLongInteger
ifFalse: [ ^ super - n ].
negative ifTrue: [ ^ (self negated + n) negated ].
n negative ifTrue: [ ^ self + n negated ].
(self < n) ifTrue: [ ^ (n - self) negated ].
" reduced to positive - smaller positive "
newDigits <- List new. borrow <- 0.
self with: n bitDo:
[:x :y | z <- (x - borrow) - y.
(z >= 0) ifTrue: [ borrow <- 0]
ifFalse: [ z <- z + 100. borrow <- 1].
newDigits addLast: z ].
result <- 0. "now normalize result by multiplication "
newDigits reverseDo: [:x | result <- result * 100 + x ].
^ result
|
* n | result |
n isShortInteger ifTrue: [ ^ self timesShort: n ].
n isLongInteger ifFalse: [ ^ super * n ].
result <- 0 asLongInteger.
digits reverseDo:
[:x | result <- (result timesShort: 100) +
(n timesShort: x)].
negative ifTrue: [ result <- result negated ].
^ result
|
abs
negative ifTrue: [ ^ self negated]
|
asFloat | r |
r <- 0.0 .
digits reverseDo: [ :x | r <- r * 100.0 + x asFloat].
negative ifTrue: [ r <- r negated ].
^ r.
|
bitShift: n
(n >= 0)
ifTrue: [ ^ self * (2 raisedTo: n) ]
ifFalse: [ ^ self quo: (2 raisedTo: n negated)]
|
coerce: n
^ n asLongInteger
|
digits
^ digits
|
generality
^ 4 "generality value - used in mixed type arithmetic "
|
isLongInteger
^ true
|
isShortInteger
" override method in class Integer "
^ false
|
negated
^ LongInteger new; sign: negative not digits: digits
|
negative
^ negative
|
new
"override restriction from class Integer"
^ self
|
quo: value | a b quo result |
result <- 0.
a <- self abs. b <- value abs.
[a > b] whileTrue:
[ quo <- (a asFloat quo: b). result <- result + quo.
a <- a - (b * quo) ].
^ result
|
sign: s digits: d
negative <- s.
digits <- d.
|
printString | str |
str <- negative ifTrue: [ '-' ] ifFalse: [ '' ].
digits reverseDo: [:x | str <- str ,
(x quo: 10) printString , (x rem: 10) printString ].
^ str
|
timesShort: value | y z carry newDigits |
y <- value abs.
carry <- 0.
newDigits <- digits collect:
[:x | z <- x * y + carry.
carry <- z quo: 100.
z - (carry * 100)].
(carry > 0) ifTrue: [ newDigits <- newDigits grow: carry ].
^ LongInteger new; sign: (negative xor: value negative)
digits: newDigits
|
with: n bitDo: aBlock | d di dj |
" run down two digits lists in parallel doing block "
di <- digits size.
d <- n digits.
dj <- d size.
(1 to: (di max: dj)) do: [:i |
aBlock value:
((i <= di) ifTrue: [ digits at: i] ifFalse: [0])
value:
((i <= dj) ifTrue: [ d at: i] ifFalse: [0]) ]
]
Methods Magnitude 'all'
<= value
^ (self < value) or: [ self = value ]
|
< value
^ (self <= value) and: [ self ~= value ]
|
>= value
^ value <= self
|
> value
^ (value < self)
|
= value
^ (self == value)
|
~= value
^ (self = value) not
|
between: low and: high
^ (low <= self) and: [ self <= high ]
|
isChar
^ false
|
max: value
^ (self < value)
ifTrue: [ value ]
ifFalse: [ self ]
|
min: value
^ (self < value)
ifTrue: [ self ]
ifFalse: [ value ]
]
Methods Number 'all'
isNumber
^ true
|
maxgen: value
(self isNumber and: [ value isNumber ])
ifFalse: [ ^ smalltalk error:
'arithmetic on non-numbers' ].
^ (self generality > value generality)
ifTrue: [ self ]
ifFalse: [ value coerce: self ]
|
+ value
^ (self maxgen: value) + (value maxgen: self)
|
- value
^ (self maxgen: value) - (value maxgen: self)
|
< value
^ (self maxgen: value) < (value maxgen: self)
|
= value
^ value isNumber
ifTrue: [ (self maxgen: value) = (value maxgen: self) ]
ifFalse: [ false ]
|
* value
^ (self maxgen: value) * (value maxgen: self)
|
/ value
^ (self maxgen: value) / (value maxgen: self)
|
// value
" integer division, truncate towards negative infinity"
" see quo: "
^ (self / value) floor
|
\\ value
" remainder after integer division "
^ self - (self // value * value)
|
abs
^ (self < 0)
ifTrue: [ 0 - self ]
ifFalse: [ self ]
|
ceiling | i |
i <- self truncated.
^ ((self positive) and: [ self ~= i ])
ifTrue: [ i + 1 ]
ifFalse: [ i ]
|
copy
^ self
|
exp
^ self asFloat exp
|
floor | i |
i <- self truncated.
^ ((self negative) and: [ self ~= i ])
ifTrue: [ i - 1 ]
ifFalse: [ i ]
|
fractionalPart
^ self - self truncated
|
isInteger
^ self isLongInteger or: [ self isShortInteger ]
|
ln
^ self asFloat ln
|
log: value
^ self ln / value ln
|
negated
^ 0 - self
|
negative
^ self < 0
|
positive
^ self >= 0
|
quo: value
^ (self maxgen: value) quo: (value maxgen: self)
|
raisedTo: x | y |
x negative
ifTrue: [ ^ 1 / (self raisedTo: x negated) ].
x isShortInteger
ifTrue: [ (x = 0) ifTrue: [ ^ 1 ].
y <- (self raisedTo: (x quo: 2)) squared.
x odd ifTrue: [ y <- y * self ].
^ y ]
"use logrithms to do exponeneation"
ifFalse: [ ^ ( x * self ln ) exp ]
|
reciprocal
^ 1 / self
|
rem: value
^ self - ((self quo: value) * value)
|
roundTo: value
^ (self / value ) rounded * value
|
sign
^ (self = 0) ifTrue: [ 0 ]
ifFalse: [ self / self abs ]
|
sqrt
^ (self negative)
ifTrue: [ smalltalk error: 'sqrt of negative']
ifFalse: [ self raisedTo: 0.5 ]
|
squared
^ self * self
|
strictlyPositive
^ self > 0
|
to: value
^ Interval new; lower: self; upper: value; step: 1
|
to: value by: step
^ Interval new; lower: self; upper: value; step: step
|
trucateTo: value
^ (self / value) trucated * value
]
Methods Random 'all'
between: low and: high
" return random number in given range "
^ (self next * (high - low)) + low
|
next
" convert rand integer into float between 0 and 1 "
^ (<3> rem: 1000) / 1000
|
next: value | list |
" return a list of random numbers of given size "
list <- List new.
value timesRepeat: [ list add: self next ].
^ list
|
randInteger: value
^ 1 + (<3> rem: value)
|
set: value
" set seed for random number generator "
<55 value>
]